/* Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#include <sstream>
#include <iomanip>
#include <cstdint>
#include "common.h"

time_t GetAsnDate(const ASN1_TIME *time)
{
    struct tm t = {0};
    string str  = (char *)time->data;
    size_t i    = 0;

    if (time->type == V_ASN1_UTCTIME) { // two digit year
        t.tm_year  = (str[i++] - '0') * 10; // 年份的10位
        t.tm_year += (str[i++] - '0');
        // 小于70代表2000年后，需要+100
        if (t.tm_year < 70) {
            t.tm_year += 100;
        }
    } else if (time->type == V_ASN1_GENERALIZEDTIME) { // four digit year
        t.tm_year  = (str[i++] - '0') * 1000; // 年份的1000位
        t.tm_year += (str[i++] - '0') * 100;  // 年份的100位
        t.tm_year += (str[i++] - '0') * 10;   // 年份的10位
        t.tm_year += (str[i++] - '0');
        t.tm_year -= 1900; // 1900年开始
    }

    t.tm_mon   = (str[i++] - '0') * 10; // 月份的10位
    t.tm_mon  += (str[i++] - '0') - 1;  // 起始是0，所以需要-1
    t.tm_mday  = (str[i++] - '0') * 10; // 天的10位
    t.tm_mday += (str[i++] - '0');
    t.tm_hour  = (str[i++] - '0') * 10; // 时的10位
    t.tm_hour += (str[i++] - '0');
    t.tm_min   = (str[i++] - '0') * 10; // 分的10位
    t.tm_min  += (str[i++] - '0');
    t.tm_sec   = (str[i++] - '0') * 10; // 秒的10位
    t.tm_sec  += (str[i++] - '0');

    return timegm(&t);
}

static uint8_t hex2byte(char c)
{
    if (c >= '0' && c <= '9') {
        return (uint8_t)(c - '0');
    } else if (c >= 'a' && c <= 'f') {
        return (uint8_t)(c - 'a') + 10; // 转换为10进制整数
    } else if (c >= 'A' && c <= 'F') {
        return (uint8_t)(c - 'A') + 10; // 转换为10进制整数
    } else {
        debug_log(DLOG_ERROR, "invalid char(%c)", c);
        return 0;
    }
}

void ConvertStringToBytes(const char *input, size_t input_len, uint8_t *output, size_t output_len)
{
    // 每2位字符串转换成1个字节
    if (output_len != input_len / 2) {
        debug_log(DLOG_ERROR, "invalid length for convert, input len: %lu, output len: %lu", input_len, output_len);
        return;
    }

    for (size_t i = 0; i < output_len; i++) {
        output[i] = hex2byte(input[i * 2]) << 4 | hex2byte(input[i * 2 + 1]);
    }
}

string ConvertBytesToString(const uint8_t *input, size_t input_len)
{
    stringstream ss;
    for (size_t i = 0; i < input_len; i++) {
        ss << hex << setw(2) << setfill('0') << static_cast<int>(input[i]);
    }

    return ss.str();
}

string base64Encode(const vector<uint8_t>& data)
{
    string base64 = "";
    int32_t val = 0;
    int32_t valb = -6;

    for (uint8_t byte : data) {
        val = (val << 8) + byte;
        valb += 8;
        while (valb >= 0) {
            base64.push_back(base64_table[(val >> valb) & 0x3F]);
            valb -= 6;
        }
    }

    if (valb > -6) {
        base64.push_back(base64_table[((val << 8) >> (valb + 8)) & 0x3F]);
    }

    while (base64.size() % 4) {
        base64.push_back('=');
    }

    return base64;
}
